package com.mocoop.plugin.ajax;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.util.Log;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.Request.Method;
import com.mocoop.activity.MocoopActivity;
import com.mocoop.activity.MocoopTabHost.MocoopTabHostListener;
import com.mocoop.commom.MyOSS;
import com.mocoop.commom.MyTaskCallBack;
import com.mocoop.commom.MyOSS.MyOSSCallBack;
import com.mocoop.dao.AjaxWorkerDao;
import com.mocoop.dao.AjaxWorkerDaoImp;
import com.mocoop.entity.AjaxInfo;
import com.mocoop.entity.AjaxInfo.FileProgress;
import com.mocoop.entity.AjaxInfo.UploadAttachmentFilesInfo;
import com.mocoop.ui.MenuItem;

public class AjaxWorker {
	public static Map<String, FileProgress> mapProgress = new HashMap<String, FileProgress>();

	private AjaxWorkerDao ajaxWorkerDao;
	private AjaxWorkerListener ajaxWorkerListener;
	private Activity activity;

	private MocoopActivity getMocoopActivity() {
		return (MocoopActivity) activity;
	}

	private MocoopTabHostListener getMocoopTabHost() {
		try {
			return (MocoopTabHostListener) activity;
		} catch (Exception e) {
			return null;
		}
	}

	public AjaxWorkerListener getAjaxWorkerListener() {
		return ajaxWorkerListener;
	}

	public void setAjaxWorkerListener(AjaxWorkerListener ajaxWorkerListener) {
		this.ajaxWorkerListener = ajaxWorkerListener;
	}

	public AjaxWorker(Activity activity, String userID) {
		this.activity = activity;
		ajaxWorkerDao = new AjaxWorkerDaoImp(activity, userID);
	}

	// 内部监听
	private AjaxWorkerListener innerListener = new AjaxWorkerListener() {
		@Override
		public void completedRequst(AjaxInfo ajaxInfo) {
			getMocoopTabHost().messageCountController("remark", MenuItem.ENDUPLOAD);
			JSONObject endObj = new JSONObject();
			try {
				endObj.put("type", "ajaxCompleted");
				endObj.put("ajaxID", ajaxInfo.getId());
				endObj.put("result", ajaxInfo.getTransferState());
				endObj.put("matchIDs", ajaxInfo.getMatchIDs());
			} catch (JSONException e) {
				e.printStackTrace();
			}
			if (getMocoopTabHost() != null) {
				if (ajaxInfo.getTransferState().equals("failed")) {
					getMocoopTabHost().messageCountController("remark", MenuItem.ERROR);
				} else {
					if (ajaxWorkerDao.checkFailedExist()) {
						getMocoopTabHost().messageCountController("remark", MenuItem.ERROR);
					} else {
						getMocoopTabHost().messageCountController("remark", MenuItem.BEFORESTATUS);
					}
				}
			}

			getMocoopActivity().notificationToUI("javascript:basic.eventNotification('" + endObj.toString() + "');", ajaxInfo.getNoticePages());
			if (ajaxWorkerListener != null)
				ajaxWorkerListener.completedRequst(ajaxInfo);
		}

		@Override
		public void beginRequst(AjaxInfo ajaxInfo) {
			JSONObject endObj = new JSONObject();
			try {
				endObj.put("type", "ajaxStarted");
				endObj.put("ajaxID", ajaxInfo.getId());
				endObj.put("matchIDs", ajaxInfo.getMatchIDs());
			} catch (JSONException e) {
			}

			if (getMocoopTabHost() != null)
				getMocoopTabHost().messageCountController("remark", MenuItem.UPLOADING);

			getMocoopActivity().notificationToUI("javascript:basic.eventNotification('" + endObj.toString() + "');", ajaxInfo.getNoticePages());
			if (ajaxWorkerListener != null)
				ajaxWorkerListener.completedRequst(ajaxInfo);
		}
	};

	public void executeRequestBiz(final AjaxInfo ajaxInfo) throws JSONException {

		if (!getMocoopActivity().isNetworkConnected()) {
			ajaxInfo.setTransferState("failed");
		} else {
			ajaxInfo.setTransferState("uploading");
		}

		ajaxWorkerDao.execute("update T_CloudDataTransferCenter set FCloudDataTransferState = ? where FCloudDataTransferID = ?", new String[] { ajaxInfo.getTransferState(),
				ajaxInfo.getId().toString() });

		if (ajaxInfo.getSqlOperation().getSQLOfAjaxStarted() != null && !"".equals(ajaxInfo.getSqlOperation().getSQLOfAjaxStarted())) {
			executeAllSQL(ajaxInfo.getSqlOperation().getSQLOfAjaxStarted().split(";"), ajaxInfo.getTransferState(), ajaxInfo.getId().toString());
		}

		innerListener.beginRequst(ajaxInfo);

		MyTaskCallBack myTaskCallBack = new MyTaskCallBack() {
			int i = 0;

			@Override
			public void onSuccess(Object obj) {
				Log.d("RZZ", "上传结束" + obj.toString());
				if (i++ > 0) {
					return;
				}
				AjaxInfo info = new AjaxInfo();
				info.setId(ajaxInfo.getId());
				info.setEndTime(new Date().getTime());
				if (obj instanceof Exception) {
					info.setTransferState("failed");
					info.setErrorMessage(obj.toString());
				} else {
					info.setTransferState("success");
					info.setResponseData(obj.toString());
				}
				ajaxWorkerDao.update(info);

				info.setMatchIDs(ajaxInfo.getMatchIDs());
				info.setNoticePages(ajaxInfo.getNoticePages());

				String id = ajaxInfo.getId().toString();

				if (ajaxInfo.getSqlOperation().getSQLOfAjaxCompleted() != null && !"".equals(ajaxInfo.getSqlOperation().getSQLOfAjaxCompleted())) {
					executeAllSQL(ajaxInfo.getSqlOperation().getSQLOfAjaxCompleted().split(";"), info.getTransferState(), id);
				}

				try {
					JSONObject response = new JSONObject(obj.toString());
					if (response.getInt("status") == 200 && ajaxInfo.getSqlOperation().getSQLOfAjaxSuccess() != null
							&& !"".equals(ajaxInfo.getSqlOperation().getSQLOfAjaxSuccess())) {
						String serviceID = response.getString("keyID");
						executeAllSQL(ajaxInfo.getSqlOperation().getSQLOfAjaxSuccess().split(";"), ajaxInfo.getSqlOperation().getSQLOfAjaxException().split(";"), serviceID);
					}
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					// e.printStackTrace();
				}

				innerListener.completedRequst(info);
			}
		};

		if (ajaxInfo.getUploadAttachmentFilesInfo() != null && ajaxInfo.getUploadAttachmentFilesInfo().size() > 0) {
			FileUploadCallBack fileUploadCallBack = new FileUploadCallBack(ajaxInfo, myTaskCallBack);
			for (UploadAttachmentFilesInfo attachmentFilesInfo : ajaxInfo.getUploadAttachmentFilesInfo()) {
				attachmentFilesInfo.setFileProgress(initFileProgress(attachmentFilesInfo));
			}
			uploadFiles(ajaxInfo.getUploadAttachmentFilesInfo().get(0), fileUploadCallBack);
		} else {
			request(ajaxInfo, myTaskCallBack);
		}
	}

	private class FileUploadCallBack implements MyOSSCallBack {
		private AjaxInfo ajaxInfo;
		private int i = 0;
		private MyTaskCallBack myTaskCallBack;

		public FileUploadCallBack(AjaxInfo ajaxInfo, MyTaskCallBack myTaskCallBack) {
			super();
			this.ajaxInfo = ajaxInfo;
			this.myTaskCallBack = myTaskCallBack;
		}

		@Override
		public void onError(boolean isOriginal, String fileID, Object obj) {
			Log.d("RZZ", "上传第" + (i + 1) + "张图片出现异常，异常：" + obj.toString());
			myTaskCallBack.onSuccess(new Exception("uploadFileException"));
		}

		@Override
		public synchronized void onSuccess(boolean isOriginal, String fileID, Object progressID) {

			if (isOriginal) {
				i++;
				if (ajaxInfo.getUploadAttachmentFilesInfo().size() > i) {
					Log.d("RZZ", "上传第" + (i + 1) + "张图片,图片ID:" + progressID);

					uploadFiles(ajaxInfo.getUploadAttachmentFilesInfo().get(i), this);
				} else {
					request(ajaxInfo, myTaskCallBack);
				}

				mapProgress.remove(progressID);

			}
		}

		@Override
		public void onProgress(FileProgress fileProgress) {
			// mapProgress.put(fileProgress.getProgressID(), fileProgress);
			// actionProgress(1, fileProgress);
		}

	}

	private FileProgress initFileProgress(UploadAttachmentFilesInfo uploadAttachmentFilesInfo) {
		boolean isOnlyThumbnail = true;
		FileProgress fileProgress = new FileProgress();
		fileProgress.setProgressID(uploadAttachmentFilesInfo.getThumbnailFileKey());
		if (uploadAttachmentFilesInfo.getOriginalFileKey() != null) {
			isOnlyThumbnail = false;
			fileProgress.setOnlyThumbnail(isOnlyThumbnail);
		}
		fileProgress.setOnlyThumbnail(isOnlyThumbnail);
		mapProgress.put(fileProgress.getProgressID(), fileProgress);
		return fileProgress;
	}

	private void uploadFiles(UploadAttachmentFilesInfo uploadAttachmentFilesInfo, MyOSSCallBack uploadCallBack) {
		if (uploadAttachmentFilesInfo.getOriginalFileKey() != null) {
			MyOSS.upload(true, uploadAttachmentFilesInfo.getFileProgress(), uploadAttachmentFilesInfo.getOriginalFileKey(), uploadAttachmentFilesInfo.getOriginalFilePath(),
					uploadCallBack);
		}
		MyOSS.upload(false, uploadAttachmentFilesInfo.getFileProgress(), uploadAttachmentFilesInfo.getThumbnailFileKey(), uploadAttachmentFilesInfo.getThumbnailFilePath(),
				uploadCallBack);
	}

	public void request(AjaxInfo ajaxInfo, final MyTaskCallBack myTaskCallBack) {

		int method = 1;
		if (ajaxInfo.getMethod().equalsIgnoreCase("get")) {
			method = Method.GET;
		} else if (ajaxInfo.getMethod().equalsIgnoreCase("post")) {
			method = Method.POST;
		} else if (ajaxInfo.getMethod().equalsIgnoreCase("delete")) {
			method = Method.DELETE;
		} else if (ajaxInfo.getMethod().equalsIgnoreCase("put")) {
			method = Method.PUT;
		}
		JSONObject params = null;
		try {
			params = new JSONObject(ajaxInfo.getRequestData());
		} catch (JSONException e) {
			e.printStackTrace();
		}

		getMocoopActivity().ajaxRequest(method, ajaxInfo.getUrl(), params, new Response.Listener<JSONObject>() {
			@Override
			public void onResponse(JSONObject response) {
				myTaskCallBack.onSuccess(response);
			}
		}, new Response.ErrorListener() {
			@Override
			public void onErrorResponse(VolleyError error) {
				myTaskCallBack.onSuccess(new Exception(error.toString()));
			}
		}, 0);
	}

	private void executeAllSQL(String sqls[], String status, String id) {
		for (String sql : sqls) {
			sql += ";";
			String[] params = new String[getOccur(sql, "?")];
			for (int i = 0; i < params.length; i++) {
				params[i] = status + "#" + id;
			}
			ajaxWorkerDao.execute(sql, params);
		}
	}

	private void executeAllSQL(String sqls[], String expSqls[], String id) {
		for (int k = 0; k < sqls.length; k++) {
			String sql = sqls[k] + ";";
			String[] params = new String[getOccur(sql, "?")];
			for (int i = 0; i < params.length; i++) {
				params[i] = id;
			}
			Exception e = ajaxWorkerDao.execute(sql, params);
			if (e != null) {
				String[] expParams = new String[getOccur(expSqls[k], "?")];
				for (int i = 0; i < expParams.length; i++) {
					expParams[i] = id;
				}
				ajaxWorkerDao.execute(expSqls[k] + ";", expParams);
			}
		}

	}

	private static int getOccur(String src, String find) {
		int o = 0;
		int index = -1;
		while ((index = src.indexOf(find, index)) > -1) {
			++index;
			++o;
		}
		return o;
	}

	public interface AjaxWorkerListener {
		public abstract void beginRequst(AjaxInfo ajaxInfo);

		public abstract void completedRequst(AjaxInfo ajaxInfo);
	}

}
